package com.yanqu.road.server.manger.activity.curio;

import com.yanqu.road.dao.impl.curio.*;
import com.yanqu.road.entity.activity.args.ValueFourParamArgs;
import com.yanqu.road.entity.config.beauty.BeautyInfo;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.config.promotion.PromotionInfo;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.curio.*;
import com.yanqu.road.entity.curio.config.CurioItemInfo;
import com.yanqu.road.entity.curio.config.CurioItemSuitInfo;
import com.yanqu.road.entity.curio.enums.eCurioSkillMessageType;
import com.yanqu.road.entity.curio.enums.eCurioSkillType;
import com.yanqu.road.entity.curio.enums.eSkillEffectRangeType;
import com.yanqu.road.entity.curio.enums.eSkillEffectType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eSkillType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.enums.eTaskType;
import com.yanqu.road.entity.player.*;
import com.yanqu.road.entity.task.TaskConditionInfo;
import com.yanqu.road.entity.task.TaskInfo;
import com.yanqu.road.pb.cangbao.CurioProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.curio.CurioModule;
import com.yanqu.road.server.gameplayer.module.patrons.CombLeaderModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.BeautyModule;
import com.yanqu.road.server.gameplayer.module.player.ChildModule;
import com.yanqu.road.server.gameplayer.module.player.EarnSpeedModule;
import com.yanqu.road.server.gameplayer.module.skin.SkinModule;
import com.yanqu.road.server.manger.activity.curio.condition.BaseCurioSpecialCondition;
import com.yanqu.road.server.manger.activity.curio.condition.CurioCountCondition;
import com.yanqu.road.server.manger.activity.tonbing.TonBingMgr;
import com.yanqu.road.server.manger.activity.tonbingchannel.ChannelTonBingMgr;
import com.yanqu.road.server.manger.activity.tongbing.TongBingMgr;
import com.yanqu.road.server.manger.config.*;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.pb.PlayerPb;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.config.Config;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import static com.yanqu.road.entity.curio.enums.eSkillEffectType.BeautyAttribute;

public class CurioMgr extends TempMgr {

    /**
     * 本服最高分（实时最高分）
     * 藏品id
     */
    static Map<Integer, CurioItemMaxScore> serverCurioMaxScoreMap;

    /**
     * 分组内藏品最高分（实时最高分数成就）
     * 藏品id
     */
    static Map<Integer, BigInteger> groupCurioMaxScoreMap = new ConcurrentHashMap<>();

    /**
     * 每个藏品分数档位先到达的玩家（历史数据，展示用）
     * key  :  taskId 或者conditionId
     */
    static Map<Integer, CurioItemMaxScoreConditionData> scoreConditionDataMap;

    public static boolean needAll = true;

    private static Map<Integer, List<ICurioSkillUpgradeListener>> listMap = new ConcurrentHashMap<>();

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        serverCurioMaxScoreMap = new UserCurioItemDataDaoImpl().getMaxScoreMap();
        scoreConditionDataMap = new CurioItemMaxScoreConditionDataDaoImpl().getCurioItemMaxScoreConditionData();

        checkConditionData();
        return true;
    }

    public static void addSyncListener(int type, ICurioSkillUpgradeListener syncListener){
        listMap.putIfAbsent(type, new ArrayList<>());
        listMap.get(type).add(syncListener);
    }

    public static void notify(int type, UserCurioSkillData skillData, GamePlayer player){
        List<ICurioSkillUpgradeListener> listeners = listMap.get(type);
        if(listeners == null){
            return;
        }
        for (ICurioSkillUpgradeListener listener : listeners) {
            try {
                listener.notify(type, skillData, player);
            }catch (Exception e) {
                getLogger().error("", e);
            }
        }
    }

    private static List<CurioItemMaxScoreConditionData> checkConditionData() {
        List<CurioItemMaxScoreConditionData> changeList = new ArrayList<>();
        //修复初始档位达成数据，上一版本没有这部分数据
        for (Map.Entry<Integer, TaskInfo> entry : TaskMgr.getTaskMap().entrySet()) {
            TaskInfo taskInfo = entry.getValue();
            if(taskInfo.getType() == eTaskType.CurioScoreTask.getValue()){
                TaskConditionInfo condition = TaskMgr.getTaskConditionById(taskInfo.getTaskId());
                if(condition != null){
                    int itemId = condition.getParamList().get(2).intValue();
                    if(itemId > 0){
                        long score = condition.getParamList().get(3).longValue();
                        synchronized (scoreConditionDataMap) {
                            CurioItemMaxScoreConditionData data = scoreConditionDataMap.get(condition.getTaskId());
                            CurioItemMaxScore maxScore = serverCurioMaxScoreMap.get(itemId);
                            if (data == null && maxScore != null && maxScore.getScore() >= score) {
                                getLogger().info("藏品成就达成，玩家{}，任务{}，分数{}，档位：分数要求 {}", maxScore.getUserId(), taskInfo.getTaskId(), maxScore.getScore(), score);
                                data = new CurioItemMaxScoreConditionData();
                                data.setInsertOption();
                                data.setItemId(itemId);
                                data.setConditionId(condition.getTaskId());
                                data.setUserId(maxScore.getUserId());
                                data.setLastUpdateTime(maxScore.getLastUpdateTime());
                                data.setScore(maxScore.getScore());
                                scoreConditionDataMap.put(condition.getTaskId(), data);
                                changeList.add(data);
                            }
                        }
                    }
                }
            }
        }
        return changeList;
    }

    @Override
    public boolean save() {
        for (Map.Entry<Integer, CurioItemMaxScoreConditionData> entry : scoreConditionDataMap.entrySet()) {
            CurioItemMaxScoreConditionData data = entry.getValue();
            if(data.isInsertOption()){
                new CurioItemMaxScoreConditionDataDaoImpl().add(data);
            }else if(data.isUpdateOption()){
                new CurioItemMaxScoreConditionDataDaoImpl().update(data);
            }
        }
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    public static boolean unlockCondition(int type, List<Integer> paramValues, GamePlayer player) {
        BaseCurioSpecialCondition specialCondition = BaseCurioSpecialCondition.getCondition(type, player);
        if(specialCondition == null){
            return false;
        }
        return specialCondition.isCompleted(paramValues);
    }

    public static void calAllSkillAddition(GamePlayer player){
        Map<Integer, UserCurioSkillData> map = player.getModule(CurioModule.class).getSkillDataMap();
        if(map != null){
            try {
                calSkillAddition(new ArrayList<>(map.values()), player);
            }catch (Exception e){
                getLogger().error("", e);
            }
        }
    }

    /**
     * 技能等级变更时候才调用
     * @param skillData 技能
     * @param player 玩家
     */
    public static void calSkillAddition(UserCurioSkillData skillData, GamePlayer player) {
        long oldAddition = skillData.getAddition();
        boolean change = calSkillAddition(Collections.singletonList(skillData), player);
        SkillInfo skillInfo = SkillMgr.getSkillInfo(skillData.getSkill());
        if(skillInfo == null){
            return;
        }
        if(change) {
            eSkillEffectType effectType = eCurioSkillMessageType.getSkillEffectType(skillInfo.getType());
            eSkillEffectRangeType effectRangeType = eCurioSkillMessageType.getSkillEffectRangeType(skillInfo.getType());
            if (skillInfo.getType() == eSkillType.CurioBeautyGlamourSkill.getValue() || skillInfo.getType() == eSkillType.BeautyIntimacyAddSkill.getValue()) {
                //如果是特定职业美女技能
                SkinModule skinModule = player.getModule(SkinModule.class);
                BeautyModule beautyModule = player.getModule(BeautyModule.class);
                for (Map.Entry<Integer, UserBeauty> beautyEntry : beautyModule.getBeautyMap().entrySet()) {
                    UserBeauty beauty = beautyEntry.getValue();
                    BeautyInfo beautyInfo = BeautyMgr.getBeautyInfo(beauty.getBeautyId());
                    if (beautyInfo != null && (skillInfo.getParamList().get(2) == beautyInfo.getOccupation() || skillInfo.getParamList().get(2) == 0)) {
                        skinModule.recaclBeautyAttr(beauty, false);
                        beautyModule.syncUserBeauty(beauty);
                    }
                }
            } else if(effectType == BeautyAttribute && effectRangeType == eSkillEffectRangeType.Id){
                //如果是特定美女技能
                SkinModule skinModule = player.getModule(SkinModule.class);
                BeautyModule beautyModule = player.getModule(BeautyModule.class);
                for (Map.Entry<Integer, UserBeauty> beautyEntry : beautyModule.getBeautyMap().entrySet()) {
                    UserBeauty beauty = beautyEntry.getValue();
                    BeautyInfo beautyInfo = BeautyMgr.getBeautyInfo(beauty.getBeautyId());
                    if (beautyInfo != null && (skillInfo.getParamList().get(2) == beautyInfo.getBeautyId() || skillInfo.getParamList().get(2) == 0)) {
                        skinModule.recaclBeautyAttr(beauty, false);
                        beautyModule.syncUserBeauty(beauty);
                    }
                }
            }else if (effectType == eSkillEffectType.PatronsAttribute) {
                int param3 = skillInfo.getParamList().get(2);
                PatronsModule patronsModule = player.getModule(PatronsModule.class);
                if(param3 == 0){
                    patronsModule.onPatronsListChange(patronsModule.getUserPatronsList());
                }else if(effectRangeType == eSkillEffectRangeType.Id) {

                    //如果是特定门客技能
                    UserPatrons userPatrons = patronsModule.getUserPatrons(param3);
                    if (userPatrons != null) {
                        patronsModule.onPatronsChange(userPatrons);
                    }
                }else if(effectRangeType == eSkillEffectRangeType.All){
                    //所有门客
                    patronsModule.onPatronsListChange(patronsModule.getUserPatronsList());

                }else if(effectRangeType == eSkillEffectRangeType.Quality){
                    //特定品质
                    List<UserPatrons> syncList = new ArrayList<>();
                    for (UserPatrons userPatrons : patronsModule.getUserPatronsList()) {
                        int pz = 0;
                        if(userPatrons.getShowPromotionId() > 0){
                            PromotionInfo promotionInfo = PromotionMgr.getPromotionInfoById(userPatrons.getShowPromotionId());
                            if(promotionInfo != null){
                                if(promotionInfo.getQuality() == param3){
                                    syncList.add(userPatrons);
                                }
                            }
                        }else {
                            PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(userPatrons.getPatronsId());
                            if(patronsInfo == null){
                                continue;
                            }
                            if(patronsInfo.getQuality() == param3){
                                syncList.add(userPatrons);
                            }
                        }
                    }
                    patronsModule.onPatronsListChange(syncList);

                }else if (effectRangeType == eSkillEffectRangeType.Occupation) {
                    //全门客
                    if (skillInfo.getParamList().get(2) == 0) {
                        patronsModule.onPatronsListChange(patronsModule.getUserPatronsList());
                    } else {
                        //特定职业
                        patronsModule.onPatronsListChange(patronsModule.getUserPatronsList(param3));
                    }
                } else if (effectRangeType == eSkillEffectRangeType.CombLeader) {//特定组合首领
                    UserCombLeaderData combLeaderData = player.getModule(CombLeaderModule.class).getUserCombLeaderDataByCombId(param3);
                    if (combLeaderData != null && combLeaderData.getLeaderId() > 0) {
                        UserPatrons userPatrons = patronsModule.getUserPatrons(combLeaderData.getLeaderId());
                        if (userPatrons != null) {
                            patronsModule.onPatronsChange(userPatrons);
                        }
                    }
                }
            }

            if(eSkillEffectType.Settlement != effectType) {
                player.getModule(EarnSpeedModule.class).scheduleAddSilver();
            }

            //一直往下加
            try{
                //要异步吗
                if(skillInfo.getType() == eSkillType.TongBingSoldierSkill.getValue()){
                    // 统兵演武
                    TongBingMgr.syncTongBingPatronsAbility(player, true);
                    TonBingMgr.syncTonBingPatronsAbility(player, true);
                    ChannelTonBingMgr.syncTonBingPatronsAbility(player, true);
                }
                //子嗣体力上限
                if(skillInfo.getType() == eSkillType.ChildEnergyLimitSkill.getValue()){
                    if(oldAddition != skillData.getAddition()){
                        long add = skillData.getAddition() - oldAddition;
                        ChildModule childModule = player.getModule(ChildModule.class);
                        int maxTrainTimes = ChildMgr.getChildSiteMaxTrainTimes(player);
                        int siteCount = childModule.getChildSiteCount();
                        for (int i = 1; i <= siteCount; i++) {
                            UserChildSite userChildSite = childModule.getUserChildSite(i);
                            if(userChildSite != null && userChildSite.getTrainTimes() < maxTrainTimes){
                                if(add + userChildSite.getTrainTimes() > maxTrainTimes){
                                    userChildSite.setTrainTimes(maxTrainTimes);
                                    userChildSite.setLastRestoreTime(System.currentTimeMillis() / 1000);
                                }else {
                                    userChildSite.setTrainTimes((int)add + userChildSite.getTrainTimes());
                                }
                                childModule.syncChildSiteData(userChildSite);
                            }
                        }
                    }
                }
            }catch (Exception e){
                CurioMgr.getLogger().error("", e);
            }


            try{
                notify(skillInfo.getType(), skillData, player);
            }catch (Exception e){
                CurioMgr.getLogger().error("", e);
            }
        }
    }

    public static boolean calSkillAddition(List<UserCurioSkillData> skillDataList, GamePlayer player) {
        boolean change = false;
        CurioModule curioModule = player.getModule(CurioModule.class);
        for (UserCurioSkillData skillData : skillDataList) {

            SkillInfo skillInfo = SkillMgr.getSkillInfo(skillData.getSkill());
            if(skillInfo == null){
                continue;
            }

            long oldAddition = skillData.getAddition();

            //加成值
            long addition = 0;

            //倍率（条件值）
            long countValue = 1;

            //藏品技能
            if(skillData.getSkillType() == eCurioSkillType.CurioItemSkill.getType() || skillData.getSkillType() == eCurioSkillType.CurioItemSpecialSkill.getType()){

                //修正等级
                UserCurioItemData itemData = curioModule.getUserCurioItemData(skillData.getObjId());
                if(itemData == null){
                    continue;
                }
                CurioItemInfo itemInfo = CurioConfigMgr.getConfig().getCurioItemInfo(skillData.getObjId());
                if(itemInfo == null){
                    continue;
                }

                //基础效果技能
                if(skillData.getSkillType() == eCurioSkillType.CurioItemSkill.getType()){

                    if(itemData.getLv() != skillData.getLv()){
                        skillData.setLv(itemData.getLv());
                    }

                    addition = SkillMgr.getSkillAddition(skillInfo, skillData.getLv());

                    //星级影响基础值
                    if(itemData.getStarLv() <= itemInfo.getBaseSkillFixedAdd().size()){
                        addition += itemInfo.getBaseSkillFixedAdd().get(itemData.getStarLv() - 1);
                    }else {
                        addition += itemInfo.getBaseSkillFixedAdd().get(itemInfo.getBaseSkillFixedAdd().size() - 1);
                    }
                }

                //特殊效果技能
                if(skillData.getSkillType() == eCurioSkillType.CurioItemSpecialSkill.getType()){

                    if(itemInfo.getType() > 0){
                        BaseCurioSpecialCondition specialCondition = CurioCountCondition.getCondition(itemInfo.getType(), player);
                        if(specialCondition != null){
                            int condMax = 1;
                            if(!StringUtils.isNullOrEmpty(itemInfo.getSpecialSkillCondMax())){
                                condMax = Integer.parseInt(itemInfo.getSpecialSkillCondMax());
                            }
                            //最大值限制
                            if(itemInfo.getParamList().get(0) > 0) {
                                countValue = Math.min(specialCondition.getConditionValue(itemInfo.getParamList()) / itemInfo.getParamList().get(0), condMax);
                            }
                        }else {
                            getLogger().info("specialCondition type {}  config null", itemInfo.getType());
                        }
                    }

                    addition = SkillMgr.getSkillAddition(skillInfo, skillData.getLv());
                }

            }else if(skillData.getSkillType() == eCurioSkillType.CurioItemSuitSkill.getType()){
                //套装效果技能

                addition = SkillMgr.getSkillAddition(skillInfo, skillData.getLv());
            }

            //重要，需要兼容无前置条件的
            if(countValue <= 0){
                countValue = 1;
            }

            long newAddition = addition * countValue;
            skillData.setAddition(newAddition);
            if(newAddition != oldAddition){
                //变更
                change = true;
            }
        }
        return change;
    }

    /**
     *
     * @param skillType 技能类型
     * @param player  玩家
     * @param params3  参数3
     * @return
     */
    public static long getSkillAdditionBySkillType(int skillType, GamePlayer player, int params3){
        long addition = 0;
        CurioModule curioModule = player.getModule(CurioModule.class);
        for (Map.Entry<Integer, UserCurioSkillData> entry : curioModule.getSkillDataMap().entrySet()) {
            UserCurioSkillData skillData = entry.getValue();
            SkillInfo skillInfo = SkillMgr.getSkillInfo(skillData.getSkill());
            if(skillInfo == null){
                continue;
            }
            if(skillInfo.getType() != skillType){
                continue;
            }
            //特定条件过滤
            if(skillInfo.getParamList().get(2) != 0 && skillInfo.getParamList().get(2) != params3){
                continue;
            }
            addition += skillData.getAddition();
        }
        CurioMgr.debugLog(player.getUserId(), skillType, addition);
        return addition;
    }

    public static long calScore(UserCurioData userCurioData, Map<Integer, UserCurioItemData> curioItemDataMap){
        long score = 0;
        CurioConfig config = CurioConfigMgr.getConfig();
        for (Map.Entry<Integer, UserCurioItemData> dataEntry : curioItemDataMap.entrySet()) {
            UserCurioItemData itemData = dataEntry.getValue();
            long itemScore = config.getLevelScore(itemData.getLv(), itemData.getQuality());
            itemScore *= config.getStarScore(itemData.getStarLv(), itemData.getQuality());
            if(itemScore != itemData.getScore()){
                itemData.setScoreUpdateTime(DateHelper.getCurrentSecond());
            }
            itemData.setScore(itemScore);
            score += itemScore;
        }
        if(userCurioData.getScore() != score){
            userCurioData.setScoreUpdateTime(DateHelper.getCurrentSecond());
        }
        userCurioData.setScore(score);
        return score;
    }

    public static void uploadAllServerMaxScore() {
        List<CurioProto.CrossCurioMaxScoreTemp> tempList = new ArrayList<>();
        for (Map.Entry<Integer, CurioItemMaxScore> entry : serverCurioMaxScoreMap.entrySet()) {
            BigInteger groupValue = groupCurioMaxScoreMap.getOrDefault(entry.getKey(), BigInteger.ZERO);
            if(entry.getValue().getScore() > groupValue.longValue()){
                tempList.add(CurioProto.CrossCurioMaxScoreTemp.newBuilder().setCurioItemId(entry.getKey()).setScore(entry.getValue().getScore()).build());
            }
        }
        CurioProto.CrossCurioUploadMaxScoreMsg.Builder upload = CurioProto.CrossCurioUploadMaxScoreMsg.newBuilder();
        upload.addAllItemScore(tempList);
        upload.setNeedAll(needAll);
        GamePlayerMgr.sendPacket(0, YanQuMessageUtils.buildMessage(Protocol.C_CURIO_MAX_SCORE_UPLOAD, upload));
    }

    public static void uploadAllServerMaxScore(UserCurioItemData itemData, long userId) {

        try {

            synchronized (serverCurioMaxScoreMap) {
                CurioItemMaxScore maxScore = serverCurioMaxScoreMap.get(itemData.getItemId());
                if (maxScore == null) {
                    maxScore = new CurioItemMaxScore(itemData.getItemId(), itemData.getScore(), userId, itemData.getScoreUpdateTime());
                    serverCurioMaxScoreMap.put(itemData.getItemId(), maxScore);
                } else {
                    if (itemData.getScore() > maxScore.getScore()) {
                        maxScore.setScore(itemData.getScore());
                        maxScore.setLastUpdateTime(itemData.getScoreUpdateTime());
                        maxScore.setUserId(userId);
                    } else {
                        return;
                    }
                }
            }

            List<CurioProto.CrossCurioMaxScoreTemp> tempList = new ArrayList<>();
            BigInteger groupValue = groupCurioMaxScoreMap.getOrDefault(itemData.getItemId(), BigInteger.ZERO);

            CurioProto.CrossCurioUploadMaxScoreMsg.Builder upload = CurioProto.CrossCurioUploadMaxScoreMsg.newBuilder();

            if (itemData.getScore() > groupValue.longValue()) {
                tempList.add(CurioProto.CrossCurioMaxScoreTemp.newBuilder().setCurioItemId(itemData.getItemId()).setScore(itemData.getScore()).build());
            }
            if (tempList.size() > 0) {
                upload.addAllItemScore(tempList);
            }

            //是否有新达成的成就，要上传
            List<CurioItemMaxScoreConditionData> conditionDataList = checkConditionData();
            for (CurioItemMaxScoreConditionData conditionData : conditionDataList) {
                upload.addUser(buildItemMaxSocreUserTemp(conditionData));
            }
            upload.setNeedAll(needAll);
            GamePlayerMgr.sendPacket(0, YanQuMessageUtils.buildMessage(Protocol.C_CURIO_MAX_SCORE_UPLOAD, upload));

        }catch (Exception e){
            getLogger().error("", e);
        }
    }

    /**
     * 通知上传区服成就数据  + 藏品最高分
     */
    public static void uploadAllServerHistoryScoreConditionData() {
        CurioProto.CrossCurioUploadHistoryItemScoreReqMsg.Builder upload = CurioProto.CrossCurioUploadHistoryItemScoreReqMsg.newBuilder();

        //成就
        for (Map.Entry<Integer, CurioItemMaxScoreConditionData> entry : scoreConditionDataMap.entrySet()) {
            CurioItemMaxScoreConditionData conditionData = entry.getValue();
            CurioProto.CurioItemMaxScoreUserTemp.Builder builder = buildItemMaxSocreUserTemp(conditionData);
            if (builder == null) continue;
            upload.addUser(builder);
        }

        //最高分
        for (Map.Entry<Integer, CurioItemMaxScore> entry : serverCurioMaxScoreMap.entrySet()) {
            CurioItemMaxScore maxScore = entry.getValue();
            upload.addItemScore(CurioProto.CrossCurioMaxScoreTemp.newBuilder().setCurioItemId(entry.getKey()).setScore(maxScore.getScore()).build());
        }

        GamePlayerMgr.sendPacket(0, YanQuMessageUtils.buildMessage(Protocol.C_CURIO_HISTORY_MAX_SCORE_UPLOAD, upload));
    }

    public static CurioProto.CurioItemMaxScoreUserTemp.Builder buildItemMaxSocreUserTemp(CurioItemMaxScoreConditionData conditionData) {
        CurioProto.CurioItemMaxScoreUserTemp.Builder builder = CurioProto.CurioItemMaxScoreUserTemp.newBuilder();
        builder.setConditionId(conditionData.getConditionId());
        builder.setScore(conditionData.getScore());
        builder.setUserId(conditionData.getUserId());
        builder.setUpdateTime(conditionData.getLastUpdateTime());
        UserInfo userInfo = UserMgr.getUserInfo(conditionData.getUserId());
        if(userInfo == null){
            return null;
        }
        builder.setPlayerMsg(PlayerPb.parsePlayerBaseTempMsg(userInfo));
        return builder;
    }

    public static void updateMaxScore(HashMap<Integer, BigInteger> scoreMap, boolean allSync) {
        List<Integer> changeList = new ArrayList<>();
        synchronized (groupCurioMaxScoreMap){
            for (Map.Entry<Integer, BigInteger> entry : scoreMap.entrySet()) {
                BigInteger old = groupCurioMaxScoreMap.getOrDefault(entry.getKey(), BigInteger.ZERO);
                if(entry.getValue().compareTo(old) > 0){
                    groupCurioMaxScoreMap.put(entry.getKey(), entry.getValue());
                    changeList.add(entry.getKey());
                }
            }
        }
        if(changeList.size() > 0) {
            for (GamePlayer gamePlayer : GamePlayerMgr.getCopyPlayerList()) {
                for (Map.Entry<Integer, BigInteger> entry : groupCurioMaxScoreMap.entrySet()) {
                    if(changeList.contains(entry.getKey())) {
                        gamePlayer.notifyListener(eGamePlayerEventType.CurioMaxScoreAchieve.getValue(), new ValueFourParamArgs(entry.getValue(), entry.getKey()));
                    }
                }
            }
        }
        if(allSync){
            needAll = false;
            getLogger().info("藏宝下发全量最高评分，{}", scoreMap.size());
        }
    }

    public static void debugLog(long userId, int skillType, long addition){
        if(Config.isDebug()){
            //getLogger().error("玩家{}，藏宝系统 ==================  技能类型: {}，{}， 加成{}", userId, skillType, eCurioSkillMessageType.getMessage(skillType), addition);
        }
    }

    public static CurioProto.CurioWatchPlayerSimpleRespMsg.Builder watch(long userId) {
        CurioProto.CurioWatchPlayerSimpleRespMsg.Builder builder = CurioProto.CurioWatchPlayerSimpleRespMsg.newBuilder();

        UserInfo userInfo = UserMgr.getUserInfo(userId);
        if(userInfo == null){
            builder.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            return builder;
        }

        if(!SystemOpenMgr.offlineSystemOpen(userInfo.getSystemOpenValue(), eSystemId.Curio.getValue())){
            builder.setRet(GameErrorCode.E_SYSTEM_NO_OPEN);
            return builder;
        }

        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if(player != null){
            CurioModule module = player.getModule(CurioModule.class);
            builder.setMsg(getSyncBuilder(module.getUserCurioData(),
                    module.getCurioItemDataMap(),
                    module.getSkillDataMap(),
                    module.getCountDataMap()));

        }else {

            UserCurioData userCurioData = new UserCurioDataDaoImpl().getUserCurioData(userId);
            Map<Integer, UserCurioItemData> curioItemDataMap = new UserCurioItemDataDaoImpl().getUserCurioItemData(userId);
            Map<Integer, UserCurioSkillData> skillDataMap = new UserCurioSkillDataDaoImpl().getUserCurioSkillData(userId);
            Map<Integer, Map<Integer, UserCurioCountData>> countDataMap = new UserCurioCountDataDaoImpl().getUserCurioCountData(userId);

            builder.setMsg(getSyncBuilder(userCurioData, curioItemDataMap, skillDataMap, countDataMap));
        }
        builder.setRet(0);
        return builder;
    }

    public static CurioProto.CurioWatchPlayerItemRespMsg.Builder watchItem(long userId, int itemId) {
        CurioProto.CurioWatchPlayerItemRespMsg.Builder builder = CurioProto.CurioWatchPlayerItemRespMsg.newBuilder();

        UserInfo userInfo = UserMgr.getUserInfo(userId);
        if(userInfo == null){
            builder.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            return builder;
        }

        if(!SystemOpenMgr.offlineSystemOpen(userInfo.getSystemOpenValue(), eSystemId.Curio.getValue())){
            builder.setRet(GameErrorCode.E_SYSTEM_NO_OPEN);
            return builder;
        }

        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if(player != null){
            CurioModule module = player.getModule(CurioModule.class);
            UserCurioItemData itemData = module.getCurioItemDataMap().get(itemId);
            if(itemData == null){
                builder.setRet(GameErrorCode.E_CURIO_ITEM_NO_GET);
                return builder;
            }
            builder.setItem(CurioMgr.buildCurioItemTemp(itemData));

            Map<Integer, UserCurioSkillData> skillDataMap = module.getSkillDataMap();

            CurioConfig config = CurioConfigMgr.getConfig();
            List<Integer> suitList = config.getSuitList(itemId);
            for (Integer suitId : suitList) {
                CurioItemSuitInfo curioItemSuitInfo = config.getCurioItemSuitInfo(suitId);
                for (Integer id : curioItemSuitInfo.getCurioList()) {
                    if(id != itemId){
                        UserCurioItemData data = module.getUserCurioItemData(id);
                        if(data != null) {
                            builder.addSuitItem(CurioMgr.buildCurioItemTemp(data));
                        }
                    }
                }
            }
            for (Map.Entry<Integer, UserCurioSkillData> dataEntry : skillDataMap.entrySet()) {
                builder.addSkillTemp(CurioMgr.buildSkillTemp(dataEntry.getValue()));
            }

        }else {

            Map<Integer, UserCurioItemData> curioItemDataMap = new UserCurioItemDataDaoImpl().getUserCurioItemData(userId);

            UserCurioItemData itemData = curioItemDataMap.get(itemId);
            if(itemData == null){
                builder.setRet(GameErrorCode.E_CURIO_ITEM_NO_GET);
                return builder;
            }
            builder.setItem(CurioMgr.buildCurioItemTemp(itemData));

            Map<Integer, UserCurioSkillData> skillDataMap = new UserCurioSkillDataDaoImpl().getUserCurioSkillData(userId);

            CurioConfig config = CurioConfigMgr.getConfig();
            List<Integer> suitList = config.getSuitList(itemId);
            for (Integer suitId : suitList) {
                CurioItemSuitInfo curioItemSuitInfo = config.getCurioItemSuitInfo(suitId);
                for (Integer id : curioItemSuitInfo.getCurioList()) {
                    if(id != itemId){
                        UserCurioItemData data = curioItemDataMap.get(id);
                        if(data != null) {
                            builder.addSuitItem(CurioMgr.buildCurioItemTemp(data));
                        }
                    }
                }
            }
            for (Map.Entry<Integer, UserCurioSkillData> dataEntry : skillDataMap.entrySet()) {
                builder.addSkillTemp(CurioMgr.buildSkillTemp(dataEntry.getValue()));
            }
        }
        builder.setRet(0);
        return builder;
    }

    public static List<Integer> getSkillIdList(int skillType){
        List<SkillInfo> infoList = SkillMgr.getSkillInfoListByType(skillType);
        if(infoList == null){
            return new ArrayList<>();
        }
        List<Integer> list = new ArrayList<>();
        for (SkillInfo skillInfo : infoList) {
            list.add(skillInfo.getId());
        }
        return list;
    }

    public static CurioProto.CurioDataSyncMsg.Builder getSyncBuilder(UserCurioData userCurioData, Map<Integer, UserCurioItemData> curioItemDataMap
            , Map<Integer, UserCurioSkillData> skillDataMap, Map<Integer, Map<Integer, UserCurioCountData>> countDataMap) {
        CurioProto.CurioDataSyncMsg.Builder builder = CurioProto.CurioDataSyncMsg.newBuilder();
        if(userCurioData != null) {
            builder.setUserData(CurioMgr.buildUserDataTemp(userCurioData));
        }

        for (Map.Entry<Integer, UserCurioItemData> dataEntry : curioItemDataMap.entrySet()) {
            UserCurioItemData itemData = dataEntry.getValue();
            builder.addItem(CurioMgr.buildCurioItemTemp(itemData));
        }

        for (Map.Entry<Integer, UserCurioSkillData> dataEntry : skillDataMap.entrySet()) {
            UserCurioSkillData skillData = dataEntry.getValue();
            builder.addSkillTemp(CurioMgr.buildSkillTemp(skillData));
        }

        for (Map.Entry<Integer, Map<Integer, UserCurioCountData>> entry : countDataMap.entrySet()) {
            for (Map.Entry<Integer, UserCurioCountData> dataEntry : entry.getValue().entrySet()) {
                UserCurioCountData countData = dataEntry.getValue();
                CurioProto.CurioCountTemp.Builder countBuild = CurioProto.CurioCountTemp.newBuilder();
                countBuild.setType(countData.getType());
                countBuild.setChildType(countData.getChildType());
                countBuild.setValue(countData.getCountValue());
                builder.addCount(countBuild);
            }
        }
        return builder;
    }

    public static CurioProto.CurioUserDataTemp.Builder buildUserDataTemp(UserCurioData userCurioData) {
        CurioProto.CurioUserDataTemp.Builder userBuild = CurioProto.CurioUserDataTemp.newBuilder();
        userBuild.setScore(userCurioData.getScore());
        userBuild.setBadgeLv(userCurioData.getBadgeLv());
        userBuild.setRiverProcess(userCurioData.getRiverProcess());
        userBuild.setDrawTimes(userCurioData.getDrawTimes());
        for (Map.Entry<Integer, Integer> entry : userCurioData.getQualityDrawTimesMap().entrySet()) {
            CurioProto.CurioDrawTimesDetailTemp.Builder builder = CurioProto.CurioDrawTimesDetailTemp.newBuilder();
            builder.setQuality(entry.getKey());
            builder.setTimes(entry.getValue());
            userBuild.addTimesMap(builder);
        }
        return userBuild;
    }

    public static CurioProto.CurioItemTemp.Builder buildCurioItemTemp(UserCurioItemData userCurioItemData){
        CurioProto.CurioItemTemp.Builder builder = CurioProto.CurioItemTemp.newBuilder();
        builder.setItemId(userCurioItemData.getItemId());
        builder.setLv(userCurioItemData.getLv());
        builder.setQuality(userCurioItemData.getQuality());
        builder.setStarLv(userCurioItemData.getStarLv());
        builder.setScore(userCurioItemData.getScore());

        for (int i = 0; i < userCurioItemData.getPrivilegeList().size(); i++) {
            CurioPrivilege privilege = userCurioItemData.getPrivilegeList().get(i);
            CurioProto.CurioItemPrivilegeTem.Builder privilegeBuilder = CurioProto.CurioItemPrivilegeTem.newBuilder();
            privilegeBuilder.setType(privilege.getType());
            privilegeBuilder.setUse(privilege.isUse());
            privilegeBuilder.setExpire(privilege.getExpire());
            builder.addPrivilege(privilegeBuilder);
        }
        return builder;
    }

    public static CurioProto.CurioSkillTemp.Builder buildSkillTemp(UserCurioSkillData skillData) {
        CurioProto.CurioSkillTemp.Builder builder = CurioProto.CurioSkillTemp.newBuilder();
        builder.setSkillId(skillData.getSkill());
        builder.setObjId(skillData.getObjId());
        builder.setLv(skillData.getLv());
        builder.setSkillType(skillData.getSkillType());
        builder.setAddition(skillData.getAddition());
        return builder;
    }

    public static Map<Integer, BigInteger> getGroupCurioMaxScoreMap() {
        return groupCurioMaxScoreMap;
    }
}
